package com.hskn.hss.app.unread.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hskn.hss.app.unread.dto.NewsCountDto;
import com.hskn.hss.app.unread.dto.NoHandleCountDto;
import com.hskn.hss.app.unread.service.IUnreadService;
import com.hskn.hss.app.unread.vo.NewsCountVo;
import com.hskn.hss.app.unread.vo.NoHandleCountVo;
import com.hskn.hss.constant.CommonConstant;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.module.alarmHandleLog.domain.AlarmHandleLog;
import com.hskn.hss.module.alarmHandleLog.mapper.AlarmHandleLogMapper;
import com.hskn.hss.module.alarmcar.entity.AlarmCar;
import com.hskn.hss.module.alarmcar.mapper.AlarmCarMapper;
import com.hskn.hss.module.alarmperson.entity.AlarmPerson;
import com.hskn.hss.module.alarmperson.mapper.AlarmPersonMapper;
import com.hskn.hss.module.alarmsheshi.entity.AlarmSheshi;
import com.hskn.hss.module.alarmsheshi.mapper.AlarmSheshiMapper;
import com.hskn.hss.module.carviolation.entity.CarViolation;
import com.hskn.hss.module.carviolation.mapper.CarViolationMapper;
import com.hskn.hss.module.cases.entity.Cases;
import com.hskn.hss.module.cases.mapper.CasesMapper;
import com.hskn.hss.module.dlbjviolation.entity.DlbjViolation;
import com.hskn.hss.module.dlbjviolation.mapper.DlbjViolationMapper;
import com.hskn.hss.module.messageFlowRecords.domain.MessageFlowRecords;
import com.hskn.hss.module.messageFlowRecords.mapper.MessageFlowRecordsMapper;
import com.hskn.hss.module.notice.entity.Notice;
import com.hskn.hss.module.notice.mapper.NoticeMapper;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.mapper.TlCarMapper;
import com.hskn.hss.module.tlemergentplan.entity.TlEmergentPlan;
import com.hskn.hss.module.tlemergentplan.mapper.TlEmergentPlanMapper;
import com.hskn.hss.module.tlemployee.entity.TlEmployee;
import com.hskn.hss.module.tlemployee.mapper.TlEmployeeMapper;
import com.hskn.hss.module.tlfacilities.entity.TlFacilities;
import com.hskn.hss.module.tlfacilities.mapper.TlFacilitiesMapper;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.violationHandleLog.domain.ViolationHandleLog;
import com.hskn.hss.module.violationHandleLog.mapper.ViolationHandleLogMapper;
import com.hskn.hss.utils.AttributeUtils;
import com.hskn.hss.utils.GroupingByUtils;
import com.hskn.hss.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2020-11-16
 */
@Service
public class UnreadServiceImpl implements IUnreadService {

    @Resource
    TlEmergentPlanMapper emergentPlanMapper;
    @Resource
    CasesMapper casesMapper;
    @Resource
    NoticeMapper noticeMapper;
    @Resource
    TlEmployeeMapper employeeMapper;
    @Resource
    DlbjViolationMapper dlbjViolationMapper;
    @Resource
    CarViolationMapper carViolationMapper;
    @Resource
    AlarmSheshiMapper alarmSheshiMapper;
    @Resource
    AlarmPersonMapper alarmPersonMapper;
    @Resource
    AlarmCarMapper alarmCarMapper;
    @Resource
    AlarmHandleLogMapper alarmHandleLogMapper;
    @Resource
    ViolationHandleLogMapper violationHandleLogMapper;
    @Resource
    MessageFlowRecordsMapper messageFlowRecordsMapper;
    @Resource
    TlCarMapper tlCarMapper;
    @Resource
    TlFacilitiesMapper tlFacilitiesMapper;
    @Resource
    UserMapper userMapper;

    @Override
    @DataScope(deptAlias = "dep_id", userAlias = "personId")
    public NewsCountVo getNewsCount(BaseEntity entity, NewsCountDto newsCountDto) {
        //应急任务数量
        Integer emergentPlanCount = 0;
        //事件数量
        Integer casesCount = 0;
        //公告数量
        Integer noticeCount = 0;
        //违规数量
        Integer violationCount = 0;
        //报警数量
        Integer alarmCount = 0;

        Integer roleType = LoginUtils.getLoginUserIdentity();

        String day = DateUtil.formatDate(new Date());
        String startTime = AttributeUtils.timeCompletion(day, 's');
        String endTime = AttributeUtils.timeCompletion(day, 'e');

        String uid = LoginUtils.getUser().getUid();

        User user = userMapper.selectById(uid);
        if (Objects.isNull(user)) {
            return new NewsCountVo(emergentPlanCount, casesCount, noticeCount, violationCount, alarmCount);
        }

        TlEmployee employee = null;
        TlCar car = null;

        TlFacilities facilities = null;
        if (CommonConstant.ROLE_USER == roleType){
            //人员
            QueryWrapper<TlEmployee> employeeQueryWrapper = new QueryWrapper<>();
            employeeQueryWrapper.lambda().eq(TlEmployee::getBindaccount, uid);
            employeeQueryWrapper.last(" limit 1");
            employee = employeeMapper.selectOne(employeeQueryWrapper);
            //车辆
            QueryWrapper<TlCar> carQueryWrapper = new QueryWrapper<>();
            carQueryWrapper.lambda().eq(TlCar::getBindaccount, uid);
            carQueryWrapper.last(" limit 1");
            car = tlCarMapper.selectOne(carQueryWrapper);
            //设施
            QueryWrapper<TlFacilities> facilitiesQueryWrapper = new QueryWrapper<>();
            facilitiesQueryWrapper.lambda().eq(TlFacilities::getPrincipal, uid);
            facilitiesQueryWrapper.last(" limit 1");
            facilities = tlFacilitiesMapper.selectOne(facilitiesQueryWrapper);
        }


        //应急任务
        QueryWrapper<TlEmergentPlan> emergentPlanQueryWrapper = new QueryWrapper<>();
        List<TlEmergentPlan> emergentPlanList = new ArrayList<>();
        if (CommonConstant.ROLE_USER != roleType){
            emergentPlanList = emergentPlanMapper.selectList(emergentPlanQueryWrapper);
        } else {
            emergentPlanQueryWrapper.lambda().eq(TlEmergentPlan::getDutyperson, uid);
            emergentPlanList = emergentPlanMapper.selectList(emergentPlanQueryWrapper);
        }
        QueryWrapper<MessageFlowRecords> messageFlowRecordsQueryWrapper = new QueryWrapper<>();
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getKind, 5);
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getUserId, uid);
        messageFlowRecordsQueryWrapper.lambda().ge(MessageFlowRecords::getCreateTime, startTime);
        messageFlowRecordsQueryWrapper.lambda().le(MessageFlowRecords::getCreateTime, endTime);
        List<MessageFlowRecords> messageFlowRecordsList = messageFlowRecordsMapper.selectList(messageFlowRecordsQueryWrapper);
        emergentPlanCount = emergentPlanList.size() - messageFlowRecordsList.size();
        //事件
        QueryWrapper<Cases> casesQueryWrapper = new QueryWrapper<>();
        if (CommonConstant.ROLE_USER == roleType) {
            casesQueryWrapper.lambda().eq(Cases::getCreateUid, uid);
            casesQueryWrapper.lambda().or().eq(Cases::getCcUid, uid);
            casesQueryWrapper.lambda().or().eq(Cases::getPersonId, uid);
        }
        List<Cases> casesList = casesMapper.selectList(casesQueryWrapper);
        messageFlowRecordsQueryWrapper = new QueryWrapper<>();
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getKind, 3);
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getUserId, uid);
        messageFlowRecordsQueryWrapper.lambda().ge(MessageFlowRecords::getCreateTime, startTime);
        messageFlowRecordsQueryWrapper.lambda().le(MessageFlowRecords::getCreateTime, endTime);
        messageFlowRecordsList = messageFlowRecordsMapper.selectList(messageFlowRecordsQueryWrapper);
        casesCount = casesList.size() - messageFlowRecordsList.size();
        //通知公告
        QueryWrapper<Notice> noticeQueryWrapper = new QueryWrapper<>();
        if (CommonConstant.ROLE_USER == roleType) {
            noticeQueryWrapper.lambda().like(Notice::getReceiver, uid);
        }
        List<Notice> noticeList = noticeMapper.selectList(noticeQueryWrapper);
        messageFlowRecordsQueryWrapper = new QueryWrapper<>();
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getKind, 4);
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getUserId, uid);
        messageFlowRecordsQueryWrapper.lambda().ge(MessageFlowRecords::getCreateTime, startTime);
        messageFlowRecordsQueryWrapper.lambda().le(MessageFlowRecords::getCreateTime, endTime);
        messageFlowRecordsList = messageFlowRecordsMapper.selectList(messageFlowRecordsQueryWrapper);
        noticeCount = noticeList.size() - messageFlowRecordsList.size();

        //人员违规
        QueryWrapper<DlbjViolation> dlbjViolationQueryWrapper = new QueryWrapper<>();
        List<DlbjViolation> dlbjViolationList = new ArrayList<>();
        dlbjViolationQueryWrapper.lambda().ge(DlbjViolation::getDate, startTime);
        dlbjViolationQueryWrapper.lambda().le(DlbjViolation::getDate, endTime);
        if (Objects.nonNull(employee) && CommonConstant.ROLE_USER == roleType) {
            dlbjViolationQueryWrapper.lambda().eq(DlbjViolation::getPersonId, employee.getId());
            dlbjViolationList = dlbjViolationMapper.selectList(dlbjViolationQueryWrapper);
        } else if (CommonConstant.ROLE_USER != roleType){
            dlbjViolationList = dlbjViolationMapper.selectList(dlbjViolationQueryWrapper);
        }

        //车辆违规
        QueryWrapper<CarViolation> carViolationQueryWrapper = new QueryWrapper<>();
        List<CarViolation> carViolationList = new ArrayList<>();
        carViolationQueryWrapper.lambda().ge(CarViolation::getTime, startTime);
        carViolationQueryWrapper.lambda().le(CarViolation::getTime, endTime);
        if (Objects.nonNull(car) && CommonConstant.ROLE_USER == roleType){
            carViolationQueryWrapper.lambda().eq(CarViolation::getCarId, car.getId());
            carViolationList = carViolationMapper.selectList(carViolationQueryWrapper);
        } else if (CommonConstant.ROLE_USER != roleType){
            carViolationList = carViolationMapper.selectList(carViolationQueryWrapper);
        }

        messageFlowRecordsQueryWrapper = new QueryWrapper<>();
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getKind, 2);
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getUserId, uid);
        messageFlowRecordsQueryWrapper.lambda().ge(MessageFlowRecords::getCreateTime, startTime);
        messageFlowRecordsQueryWrapper.lambda().le(MessageFlowRecords::getCreateTime, endTime);
        messageFlowRecordsList = messageFlowRecordsMapper.selectList(messageFlowRecordsQueryWrapper);
        violationCount = dlbjViolationList.size() + carViolationList.size() - messageFlowRecordsList.size();
        //人员报警
        QueryWrapper<AlarmPerson> alarmPersonQueryWrapper = new QueryWrapper<>();
        List<AlarmPerson> alarmPersonList = new ArrayList<>();
        alarmPersonQueryWrapper.lambda().ge(AlarmPerson::getAlarmTime, startTime);
        alarmPersonQueryWrapper.lambda().le(AlarmPerson::getAlarmTime, endTime);
        if (Objects.nonNull(employee) && CommonConstant.ROLE_USER == roleType){
            alarmPersonQueryWrapper.lambda().eq(AlarmPerson::getPersonId, employee.getId());
            alarmPersonList = alarmPersonMapper.selectList(alarmPersonQueryWrapper);
        } else if (CommonConstant.ROLE_USER != roleType){
            alarmPersonList = alarmPersonMapper.selectList(alarmPersonQueryWrapper);
        }

        //车辆报警
        QueryWrapper<AlarmCar> alarmCarQueryWrapper = new QueryWrapper<>();
        List<AlarmCar> alarmCarList = new ArrayList<>();
        alarmCarQueryWrapper.lambda().ge(AlarmCar::getAlarmTime, startTime);
        alarmCarQueryWrapper.lambda().le(AlarmCar::getAlarmTime, endTime);
        if (Objects.nonNull(car) && CommonConstant.ROLE_USER == roleType){
            alarmCarQueryWrapper.lambda().eq(AlarmCar::getCarId, car.getId());
            alarmCarList = alarmCarMapper.selectList(alarmCarQueryWrapper);
        } else if (CommonConstant.ROLE_USER != roleType){
            alarmCarList = alarmCarMapper.selectList(alarmCarQueryWrapper);
        }

        //设施报警
        QueryWrapper<AlarmSheshi> alarmSheshiQueryWrapper = new QueryWrapper<>();
        List<AlarmSheshi> alarmSheshiList = new ArrayList<>();
        alarmSheshiQueryWrapper.lambda().ge(AlarmSheshi::getAlarmTime, startTime);
        alarmSheshiQueryWrapper.lambda().le(AlarmSheshi::getAlarmTime, endTime);
        if (Objects.nonNull(facilities) && CommonConstant.ROLE_USER == roleType){
            alarmSheshiQueryWrapper.lambda().eq(AlarmSheshi::getSheshiId, facilities.getId());
            alarmSheshiList = alarmSheshiMapper.selectList(alarmSheshiQueryWrapper);
        } else if (CommonConstant.ROLE_USER != roleType){
            alarmSheshiList = alarmSheshiMapper.selectList(alarmSheshiQueryWrapper);
        }

        messageFlowRecordsQueryWrapper = new QueryWrapper<>();
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getKind, 1);
        messageFlowRecordsQueryWrapper.lambda().eq(MessageFlowRecords::getUserId, uid);
        messageFlowRecordsQueryWrapper.lambda().ge(MessageFlowRecords::getCreateTime, startTime);
        messageFlowRecordsQueryWrapper.lambda().le(MessageFlowRecords::getCreateTime, endTime);
        messageFlowRecordsList = messageFlowRecordsMapper.selectList(messageFlowRecordsQueryWrapper);
        alarmCount = alarmPersonList.size() + alarmCarList.size() + alarmSheshiList.size() - messageFlowRecordsList.size();

        return new NewsCountVo(emergentPlanCount, casesCount, noticeCount, violationCount, alarmCount);
    }

    @Override
    public NoHandleCountVo getNoHandleCount(NoHandleCountDto noHandleCountDto) {
        QueryWrapper<AlarmHandleLog> alarmHandleLogQueryWrapper = new QueryWrapper<>();
        alarmHandleLogQueryWrapper.lambda().isNull(AlarmHandleLog::getDealType);
        if (StringUtils.isNotEmpty(noHandleCountDto.getRecordType())) {
            List<String> recordTypeList = Arrays.asList(noHandleCountDto.getRecordType().split(","));
            alarmHandleLogQueryWrapper.lambda().in(AlarmHandleLog::getViolationSign, recordTypeList);
        }
        List<AlarmHandleLog> alarmHandleLogList = alarmHandleLogMapper.selectList(alarmHandleLogQueryWrapper);
        Map<String, List<AlarmHandleLog>> alarmHandleLogByViolationSignMap = new HashMap<>();
        if (!alarmHandleLogList.isEmpty()) {
            alarmHandleLogByViolationSignMap = GroupingByUtils.getGroupingForMapList(alarmHandleLogList, AlarmHandleLog::getViolationSign);
        }
        QueryWrapper<ViolationHandleLog> violationHandleLogQueryWrapper = new QueryWrapper<>();
        violationHandleLogQueryWrapper.lambda().isNull(ViolationHandleLog::getDealType);
        if (StringUtils.isNotEmpty(noHandleCountDto.getRecordType())) {
            List<String> recordTypeList = Arrays.asList(noHandleCountDto.getRecordType().split(","));
            violationHandleLogQueryWrapper.lambda().in(ViolationHandleLog::getAlarmSign, recordTypeList);
        }
        List<ViolationHandleLog> violationHandleLogList = violationHandleLogMapper.selectList(violationHandleLogQueryWrapper);
        Map<String, List<ViolationHandleLog>> violationHandleLogByViolationSignMap = new HashMap<>();
        if (!alarmHandleLogList.isEmpty()) {
            violationHandleLogByViolationSignMap = GroupingByUtils.getGroupingForMapList(violationHandleLogList, ViolationHandleLog::getAlarmSign);
        }
        Integer empViolationCount = 0;
        if (violationHandleLogByViolationSignMap.containsKey("emp")) {
            empViolationCount = violationHandleLogByViolationSignMap.get("emp").size();
        }
        Integer carViolationCount = 0;
        if (violationHandleLogByViolationSignMap.containsKey("car")) {
            carViolationCount = violationHandleLogByViolationSignMap.get("car").size();
        }
        Integer empAlarmCount = 0;
        if (alarmHandleLogByViolationSignMap.containsKey("emp")) {
            empAlarmCount = alarmHandleLogByViolationSignMap.get("emp").size();
        }
        Integer carAlarmCount = 0;
        if (alarmHandleLogByViolationSignMap.containsKey("car")) {
            carAlarmCount = alarmHandleLogByViolationSignMap.get("car").size();
        }
        Integer facAlarmCount = 0;
        if (alarmHandleLogByViolationSignMap.containsKey("fac")) {
            facAlarmCount = alarmHandleLogByViolationSignMap.get("fac").size();
        }
        return new NoHandleCountVo(empViolationCount, carViolationCount, empAlarmCount
                , carAlarmCount, facAlarmCount);
    }

}
